package chef.myapplication.controller;

import chef.myapplication.Main;
import chef.myapplication.model.FileTree;
import chef.myapplication.model.ImageBox;
import chef.myapplication.model.ImageBoxes;
import javafx.beans.value.ChangeListener;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*;


import java.io.*;
import java.net.URL;
import java.util.*;

public class MainController implements Initializable,Serializable {


    private static ArrayList<String> Collections=new ArrayList<>();
    private static MainController mainController ;
    @FXML
    private BorderPane borderPane;

    @FXML
    private TreeView<FileTree.FileTreeNode> treeView;

    @FXML
    private ScrollPane scrollPane;

    @FXML
    private HBox hBoxBottom;

    @FXML
    private HBox hBoxTop;

    @FXML
    private BorderPane borderPaneRight;

    @FXML
    private Label label1;

    @FXML
    private Label label2;

    @FXML
    private ListView<String> myCollect;

    @FXML
    private Button btnCollect;
    @FXML
    private  TextField textField;
    @FXML
    private ComboBox<String> comboBox;
    @FXML
    private AnchorPane anchorPane;
    @FXML
    private ImageView imageViewPicture;

    private final FlowPane flowPane = new FlowPane();

    private final ContextMenu contextMenu =new ContextMenu();
    private static boolean flag_Cut=false;
    private final ImageView love = new ImageView(new Image(Objects.requireNonNull(Main.class.getResource("icon/收藏.png")).toString()));
    private final ImageView unLove = new ImageView(new Image(Objects.requireNonNull(Main.class.getResource("icon/取消收藏.png")).toString()));
    private final HashMap<String,FileFilter> fileFilterHashMap = new HashMap<>();
    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        File file=new File("D:\\save.TXT");
        if (!file.exists()){
            try {
                if (file.createNewFile()) {
                    System.out.println("收藏文件创建成功");
                }

            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        ObservableList<String> oldList = FXCollections.observableArrayList(Collections);
        myCollect.setItems(oldList);// 收藏夹
        mainController=this;
        listen(borderPaneRight);//事件的监听
        initContextMenu();//右键菜单的初始化
        initView();//界面初始化
        setTreeView();//文件目录树
        initComboBox();
        initFileFilterHashMap();
        ListViewListen();

    }
    private void initComboBox() {
        comboBox.getItems().addAll("*.jpg","*.png","*.jpeg","*.bmg","*.gif","所有图片");
        comboBox.getSelectionModel().select("所有图片");
        comboBox.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> getPicture(FileTree.getCurrentFile(),newValue));
        initFileFilterHashMap();
    }
    private void initFileFilterHashMap() {
        fileFilterHashMap.put("所有图片", pathname -> {
            if(pathname.getName().toLowerCase().endsWith("jpg"))
                return true;
            if(pathname.getName().toLowerCase().endsWith("png"))
                return true;
            if(pathname.getName().toLowerCase().endsWith("jpeg"))
                return true;
            if(pathname.getName().toLowerCase().endsWith("bmg"))
                return true;
            return pathname.getName().toLowerCase().endsWith("gif");
        });
        fileFilterHashMap.put("*.png",pathname -> pathname.getName().toLowerCase().endsWith("png"));
        fileFilterHashMap.put("*.jpg",pathname -> pathname.getName().toLowerCase().endsWith("jpg"));
        fileFilterHashMap.put("*.gif",pathname -> pathname.getName().toLowerCase().endsWith("gif"));
        fileFilterHashMap.put("*.jpeg",pathname -> pathname.getName().toLowerCase().endsWith("jpeg"));
        fileFilterHashMap.put("*.bmg",pathname -> pathname.getName().toLowerCase().endsWith("bmg"));
    }
    public void setLabel1() {
        long fileLength=0;
        for (int i = 0;i<ImageBoxes.getImageBoxes().size(); i++) {
            fileLength = ImageBoxes.getImageBoxes().get(i).getFile().length()+fileLength;
        }
        String tips = String.format("%d b",fileLength);
        int kb = 1024;
        tips = getImagesLength(fileLength, tips, kb);
        label1.setText("当前图片张数："+FileTree.getImageFiles().size()+" 图片总大小:"+tips+"   ");
    }

    public static String getImagesLength(long fileLength, String tips, int kb) {
        double length;
        if (fileLength> kb){
            length =(double) fileLength/kb;
            tips = String.format("%.2f",length) + "Kb";
            int mb = 1048576;
            if (fileLength> mb){
                length= (double) fileLength/mb;
                tips =  String.format("%.2f",length) + "Mb";
            }
        }
        return tips;
    }

    public void setLabel2() {
        label2.setText("已选中图片数："+ ImageBoxes.getSelectedImageBoxes().size());
    }

    public FlowPane getFlowPane(){
        return flowPane;
    }
    public static MainController getMainController() {
        return mainController;
    }
    private void listen(Pane pane){
        pane.setOnContextMenuRequested(event -> {
            ImageBoxes.contextMenu.hide();
            contextMenu.show(pane, event.getScreenX(), event.getScreenY());
            event.consume();
        });
        pane.addEventHandler(MouseEvent.MOUSE_CLICKED,event -> {
            if (event.getButton().equals(MouseButton.PRIMARY)){
                ImageBoxes.contextMenu.hide();
                this.contextMenu.hide();
                ImageBoxes.uncheck();
            }
        });
    }

    /**
     * 设置treeView
     */
    private void setTreeView(){
        treeView = new FileTree(treeView).getTreeView();
        ChangeListener<TreeItem<FileTree.FileTreeNode>> listener= (observable, oldValue, newValue) -> {
            if(newValue!=null) {
                ImageBoxes.clear();
                File myFile = newValue.getValue().getFile();
                FileTree.setCurrentFile(myFile);
                getPicture(myFile,comboBox.getValue());
                textField.setText(myFile.getAbsolutePath());
                myCollect.getSelectionModel().select(-1);
            }
        };
        treeView.getSelectionModel().selectedItemProperty().addListener(listener);
    }
    /**
     * 初始化界面
     */
    private void  initView(){
        borderPane.setFocusTraversable(false);
        borderPane.getStyleClass().add("edge-to-edge");
        scrollPane.getStyleClass().add("edge-to-edge");
        treeView.getStyleClass().add("edge-to-edge");
        myCollect.getStyleClass().add("edge-to-edge");
        imageViewPicture.setImage(new Image(Objects.requireNonNull(Main.class.getResource("icon/皮卡丘.png")).toString()));
        imageViewPicture.setPreserveRatio(true);
        imageViewPicture.setFitWidth(35);
        flowPane.setFocusTraversable(false);
        flowPane.setCache(true);
        flowPane.setHgap(30);
        flowPane.setVgap(30);
        flowPane.setPadding(new Insets(50,70,50,100));
        scrollPane.setFocusTraversable(false);
        scrollPane.setFitToWidth(true);
        scrollPane.setFitToHeight(true);
        VBox vBox =new VBox();
        vBox.setFocusTraversable(false);
        ImageView imageView =new ImageView(Objects.requireNonNull(Main.class.getResource("icon/图片.png")).toString());
        imageView.setFocusTraversable(false);
        imageView.setFitWidth(300);
        imageView.setPreserveRatio(true);
        vBox.getChildren().add(imageView);
        vBox.setAlignment(Pos.CENTER);
        scrollPane.setContent(vBox);
        AnchorPane.setRightAnchor(comboBox,1.0);
        AnchorPane.setLeftAnchor(imageViewPicture,10.0);
        AnchorPane.setTopAnchor(imageViewPicture,1.0);
        btnCollect.setStyle("-fx-background-color: transparent");
        btnCollect.setOnAction(event -> collect());
        ImageView love = new ImageView(new Image("file:src/main/resources/icon/收藏.png"));
        love.setPreserveRatio(true);
        love.setFitWidth(30);
        btnCollect.setGraphic(love);
        textField.setEditable(false);
    }
    /**
     * 得到缩略图
     *
     */
    public  void Refresh(){
        this.getPicture(FileTree.getCurrentFile(),comboBox.getValue());
    }
    private void getPicture(File myFile,String fileFilter){
        long startTime = System.currentTimeMillis();
        FileTree.getImageFiles().clear();
        ImageBoxes.getSelectedImageBoxes().clear();
        ImageBoxes.getImageBoxes().clear();
        if(!IsCollect())
        {
           setLove();
        }
        else {
             setUnLove();
        }
        if(!myFile.isDirectory()){
            setNoImageView();
            return;
        }
        long time =System.currentTimeMillis()-startTime;
        System.out.println("getPicture"+time);
        /*
        文件过滤
         */
        File[] files = myFile.listFiles(fileFilterHashMap.get(fileFilter));
        if (files == null||files.length==0) {
            setNoImageView();
            return;
        }
        FileTree.getImageFiles().addAll(List.of(files));
        buildFlowPane(files);
    }
    private void setLove() {
        love.setPreserveRatio(true);
        love.setFitWidth(30);
        btnCollect.setGraphic(love);
    }

    private void setUnLove() {
        unLove.setPreserveRatio(true);
        unLove.setFitWidth(30);
        btnCollect.setGraphic(unLove);
    }


    /*
    目录下没有图片的界面
     */
    private void setNoImageView(){
        VBox vBox = new VBox();
        vBox.setAlignment(Pos.CENTER);
        ImageView imageView = new ImageView(Objects.requireNonNull(Main.class.getResource("icon/图片.png")).toString());
        Label label = new Label("当前目录下没有可以显示的图片图片");
        label.setAlignment(Pos.CENTER);
        label.setStyle("-fx-font-size: 30");
        label.setStyle("-fx-color-label-visible: \t#00FFFF");
        vBox.getChildren().addAll(imageView,label);
        scrollPane.setContent(vBox);
        label1.setText("");
        label2.setText("");
    }
    /**
     * 得到缩略图
     *
     */
    private void buildFlowPane(File[] files){
        long startTime = System.currentTimeMillis();
        flowPane.addEventHandler(MouseEvent.MOUSE_CLICKED, event -> {
        });
        setLabel1();
        flowPane.getChildren().clear();
        scrollPane.setContent(flowPane);
        for (File file : files) {
            ImageBox imageBox =new ImageBox(file);
            flowPane.getChildren().add(imageBox);
            ImageBoxes.getImageBoxes().add(imageBox);
        }
        long time =System.currentTimeMillis()-startTime;
        System.out.println("build flowPane:"+time);
        setLabel1();
    }

    private void initContextMenu(){
        MenuItem item1 = new MenuItem("粘贴");
        MenuItem item2 = new MenuItem("全选");
        MenuItem item3 = new MenuItem("取消全选");
        contextMenu.getItems().addAll(item1,item2);
        item1.setOnAction(event -> {
            try {
                ImageBoxes.paste();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        });
        item2.setOnAction(event -> ImageBoxes.checkAll());
        item3.setOnAction(event -> ImageBoxes.uncheck());
    }

    public void setFlag_Cut(boolean flag) {
        flag_Cut=flag;
    }

    public boolean getFlag_Cut() {
        return flag_Cut;
    }

    private void collect() {

        if (FileTree.getCurrentFile()==null) {
            System.out.println("没有选中目标");
            return;
        }
        System.out.println("current File="+FileTree.getCurrentFile());
        if (IsCollect()){
            setLove();
        }
        else {
            setUnLove();
        }
            for(int i=0;i<Collections.size();i++)
            {
                if(Objects.equals(Collections.get(i), FileTree.getCurrentFile().getAbsolutePath()))
                {
                    Collections.remove(i);
                    ObservableList<String> strList = FXCollections.observableArrayList(Collections);
                    String string = FileTree.getCurrentFile().getAbsolutePath();
                    myCollect.setItems(strList);
                    myCollect.getSelectionModel().select(string);
                    return;
                }
            }
            Collections.add(FileTree.getCurrentFile().getAbsolutePath());
            String string = FileTree.getCurrentFile().getAbsolutePath();
            ObservableList<String> strList = FXCollections.observableArrayList(Collections);
            myCollect.setItems(strList);
            myCollect.getSelectionModel().select(string);
        }
    public void ListViewListen() {
        myCollect.getSelectionModel().selectedItemProperty().addListener((arg0, arg1, arg2) -> {
            if(arg2!=null) {
                treeView.getSelectionModel().select(-1);
                File file= new File(arg2);
                FileTree.setCurrentFile(file);
                if (!Collections.contains(FileTree.getCurrentFile().getAbsolutePath())){
                    return;
                }
                MainController.getMainController().getPicture(file,comboBox.getValue());
                textField.setText(file.getAbsolutePath());
            }
        });
    }
    public static void writeObj() {
        try {
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(".\\save.TXT"));
            objectOutputStream.writeObject(Collections);
            objectOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void readObj() {
        try {
            ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(".\\save.TXT"));
            try {
                Collections = (ArrayList<String>) objectInputStream.readObject();
                objectInputStream.close();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    private  boolean IsCollect()
    {
        for (String collection : Collections) {

            if (Objects.equals(collection, FileTree.getCurrentFile().getAbsolutePath()))
                return true;
        }
        return false;
    }

    public ContextMenu getContextMenu() {
        return  contextMenu;
    }
}
